package com.lw;

import com.server.MyServlet2;

import javax.servlet.Servlet;
import javax.servlet.ServletException;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;

/**
 * 处理socket请求
 */
public class SocketProcessor implements Runnable{

    private Socket socket;
    private  Tomcat tomcat;

    public SocketProcessor(Socket socket,Tomcat tomcat){
        this.socket = socket;
        this.tomcat = tomcat;
    }

    @Override
    public void run() {
        processSocket(socket);
    }

    /**
     * 处理socket请求方法
     * @param socket
     */
    private void processSocket(Socket socket){
        InputStream inputStream = null;
        try {
            inputStream = socket.getInputStream();

            byte[] bytes = new byte[1024];
            inputStream.read(bytes);

            //按照http协议，解析字节流，遇到一个空格就退出

            //解析method
            int pos = 0;
            int begin = 0,end = 0;
            for (;pos<bytes.length;pos++,end++){
                if(bytes[pos]==' ') break;//遇到一个空格就退出
            }

            //组合空格之前的字节流，转换成字符串就是请求方法
            StringBuilder method = new StringBuilder();
            while(begin<end){
                method.append((char)bytes[begin]);
                begin++;
            }
            System.out.println(method.toString());//输出 GET,POST等请求方法

            //解析url
            //下面++是因为需要跳过空格
            pos++;
            begin++;
            end++;

            while (pos< bytes.length){
                if(bytes[pos]==' ') break;

                pos++;
                end++;
            }
            StringBuilder url = new StringBuilder();
            while(begin<end){
                url.append((char)bytes[begin]);
                begin++;
            }
            System.out.println(url.toString());

            //解析协议版本
            pos++;
            begin++;
            end++;

            while (pos< bytes.length){
                if(bytes[pos]=='\r'&&bytes[pos+1]=='\n') break; //协议版本是遇到回车换行符算结束  \r回车  \n 换行符

                pos++;
                end++;
            }
            StringBuilder protocl = new StringBuilder();
            while(begin<end){
                protocl.append((char)bytes[begin]);
                begin++;
            }
            System.out.println(protocl.toString());

            System.out.println("------------------请求头区域------------------");

            //解析请求头
            while (pos< bytes.length){
                boolean headParseFinish = false;

                //下面加2是因为要跳过 回车符，换行符两个符号，而不再是空格
                pos += 2;
                begin += 2;
                end += 2;

                while (pos< bytes.length){
                    if(bytes[pos]=='\r'&&bytes[pos+1]=='\n') break; //协议版本是遇到回车换行符算结束

                    pos++;
                    end++;
                }
                StringBuilder head = new StringBuilder();
                while(begin<end){
                    head.append((char)bytes[begin]);
                    begin++;
                }
                if(head.toString().equals("")){//说明游标压根没移动过
                    headParseFinish = true;
                }
                System.out.println(head.toString());

                if(headParseFinish) break;

            }

            System.out.println("------------------正文区域------------------");
            //解析请求正文
            pos += 2;
            begin += 2;
            end += 2;

            while (pos< bytes.length){
                if(bytes[pos]=='\u0000') break; //协议版本是如果是空字符串，则正文没有

                pos++;
                end++;
            }
            StringBuilder body = new StringBuilder();
            while(begin<end){
                body.append((char)bytes[begin]);
                begin++;
            }
            System.out.println(body.toString());

            //返回响应
            Request request = new Request(method.toString(), url.toString(), protocl.toString(),socket);
            Response response = new Response(request);

            //匹配servlet doGet
            //requestUrl= /myserver/test  myserver是服务名    /test/XXX才是路径
            String requestUrl = url.toString();
            requestUrl = requestUrl.substring(1);
            String[] parts = requestUrl.split("/");

            String appName = parts[0];//myserver
            Context context = tomcat.getContextMap().get(appName);

            //此处需要注意  /test?name=king这种格式的路径，暂不考虑restful接口模式
            if(parts.length>1){
                String urlPattern = parts[1];
                if(urlPattern.indexOf("?")>=0){
                    urlPattern = urlPattern.substring(0,urlPattern.indexOf("?"));
                }
                Servlet servlet = context.getByUrlPattern(urlPattern);
                if(servlet!=null){
                    servlet.service(request,response);
                }else{
                    DefaultServlet defaultServlet = new DefaultServlet();
                    defaultServlet.service(request,response);
                }


                //发送响应
                response.complete();
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if(inputStream!=null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }

    }
}
